﻿using System;
using System.Collections.Generic;

namespace Serene.Criteria
{
    ///<summary>
    /// A basic usage criteria that examines the number of days installed, and number of times run
    ///</summary>
    public class BasicUsageCriteria : ICriteria
    {
        public const string RunsSinceInstallKey = "RunsSinceInstall";
        private static bool _hasBeenRun;
        private static bool _result;

        /// <summary>
        /// Number of times the application must be run in the installed for period
        /// </summary>
        protected int MustHaveRunApplication { get; set; }

        /// <summary>
        /// Number of days the user must have the application installed for before meeting this criteria
        /// </summary>
        protected int MustBeInstalledFor { get; set; }

        public BasicUsageCriteria() : this(30,15)
        {
            
        }

        public BasicUsageCriteria(int mustBeInstalledFor, int mustHaveRunApplication)
        {
            MustBeInstalledFor = mustBeInstalledFor;
            MustHaveRunApplication = mustHaveRunApplication;
        }

        public bool MeetsCriteria(IReadonlyStatus status, IDictionary<string, string> criteriaState)
        {
            if(_hasBeenRun)
                return _result;

            _hasBeenRun = true;

            var runs = 0;
            if(criteriaState.ContainsKey(RunsSinceInstallKey))
            {
                if(int.TryParse(criteriaState[RunsSinceInstallKey], out runs) == false)
                    runs = 0;
            }
            else
            {
                criteriaState.Add(RunsSinceInstallKey, "0");
            }
            runs++;
            criteriaState[RunsSinceInstallKey] = runs.ToString();

            _result = runs > MustHaveRunApplication &&
                      status.InstallationDate < DateTime.Now.AddDays(-MustBeInstalledFor);

            return _result;
        }

        public CriteriaType Type
        {
            get { return CriteriaType.And; }
        }
    }
}
